<?php

abstract class Dcmp_Domain_Base{

	protected $currentStep = 'initialize';
	protected $nextStep = 'initialize';
	protected $routerClass = NULL;
	protected $filterClass = NULL;
	protected $name = NULL;
	
	private $_config = array();
	private $_application = NULL;
	
	public function __construct($application, $config = array()) {
		$this->_config = new Kd_Configuration($config);
		$this->_application = $application;
	}
	
	public function getName(){
		return $this->name;
	}
	
	public function getApplication(){
		return $this->_application;
	}
	
	public function getConfig(){
		return $this->_config;
	}
	
	protected function getPluginSettings($name = NULL){
		if(is_null($name)){
			return $this->getConfig()->getSetting('plugins', NULL);
		}

		return $this->getConfig()->getSetting('plugins.'.$name, array());
	}
	
	public function loadComponent($name){
		$componentClass = $this->getName().'_component_'.$name.'_'.$name;
		$componentClass = Kd_Loader::loadClass($componentClass);
		$componentClass = empty($componentClass)?
                                'Dcmp_Component_Component':
                                $componentClass;
		return new $componentClass($this);
	}
	
	protected function initialize() {
		$this->currentStep = 'initialize';
		$this->nextStep = 'route';
	}
	
	protected function beforeRoute(){
		$this->executePlugin('route.before', 'route');
	}	

	protected function route() {
		$this->currentStep = 'route';
		$this->nextStep = 'filter';
		Kd_Web::getRouter()->route();
	}

	protected function filter() {
		$this->currentStep = 'filter';
		$this->nextStep = 'authenticate';
	}

	protected function authenticate() {
		$this->currentStep = 'authenticate';
		$this->nextStep = 'authorization';
	}

	protected function authorization(){
		$this->currentStep = 'authorization';
		$this->nextStep = 'handler';
	}

	protected function handler() {
        $component = $this->loadComponent(Kd_Web::getRouter()->getComponent());
        $component->run();
		$this->currentStep = 'handler';
		$this->nextStep = 'output';
	}
	
	protected function beforeOutput(){
		$this->executePlugin('output.before', 'output');
	}

	protected function output() {
		$this->currentStep = 'output';
		$this->nextStep = 'finish';
	}

	protected function finish() {
		$this->currentStep = 'finish';
		$this->nextStep = NULL;
	}

	public function run() {
		while (!is_null($this->nextStep)){
			$method = $this->nextStep;
			$beforeMethod = 'before'.ucfirst($method);
			$afterMethod = 'after'.ucfirst($method);
			if(method_exists($this, $beforeMethod)){
				$this->$beforeMethod();
			}
			$this->$method();
			if(method_exists($this, $afterMethod)){
				$this->$afterMethod();
			}			
		}
	}
	
	private function executePlugin($name, $step){
		$pluginSettings = $this->getPluginSettings($name);
		foreach ($pluginSettings as $pluginName){
			$pluginClass = Kd_Loader::loadClass($this->getName().'_plugin_'.$step.'_'.$pluginName);
			$plugin = new $pluginClass($this);
			$plugin->execute();
		}		
	}
}